﻿using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace TemplateFoundation.Serialization
{
    /// <summary>
    /// Used to serialize/deserialize objects to/from XML
    /// </summary>
    public static class XmlSerializer
    {
        /// <summary>
        /// Serializes an object into an XML string
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="objectToSerialize"></param>
        /// <returns></returns>
        public static string Serialize<T>(T objectToSerialize)
        {
            var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));

            using (var memoryStream = new MemoryStream())
            {
                var xmlWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

                serializer.Serialize(xmlWriter, objectToSerialize,new XmlSerializerNamespaces(new XmlQualifiedName[0]));

                xmlWriter.Close();
                memoryStream.Close();

                var xml = Encoding.UTF8.GetString(memoryStream.GetBuffer());
                xml = xml.Substring(xml.IndexOf(Convert.ToChar(60)));
                xml = xml.Substring(0, (xml.LastIndexOf(Convert.ToChar(62)) + 1));

                return xml;
            }
        }

        /// <summary>
        /// Deserializes and object from its XML string representation
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static T Deserialize<T>(string xml)
        {
            var ser = new System.Xml.Serialization.XmlSerializer(typeof(T));
            using (var stringReader = new StringReader(xml))
            {
                var xmlReader = new XmlTextReader(stringReader);
                var deserializedObject = (T)ser.Deserialize(xmlReader);

                xmlReader.Close();
                stringReader.Close();
                return deserializedObject;
            }
        }
    }
}
